package com.wq.jdk8;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author: wangqiang20995
 * @Date:2019/2/18
 * @Description:
 * @Resource:
 */
public class InjectWater {

    private List<Set<String>> allPath = new ArrayList<>();

    private int number = 0;

    private int[] bucketsLimits = new int[]{8,6,2};

    public static void main(String args[]) {
        InjectWater injectWater = new InjectWater();
        injectWater.change(new int[]{8,0,0},new LinkedHashSet<>());

        System.out.println("找到" + injectWater.number+"种解决方案");
        for(Set<String> set : injectWater.allPath){
            System.out.println("-------------Path-------------");
            for(String node : set){
                System.out.println(node);
            }
        }
    }

    private void change(int[] buckets, Set<String> nodePath) {
        String node = buckets[0] + "," + buckets[1] + "," + buckets[2];
        if (nodePath.contains(node)) {
            return;
        }

        if (buckets[0] == 4 && buckets[1] == 4) {
            nodePath.add(node);
            this.allPath.add(nodePath);
            this.number++;
            return;
        }

        for (int i = 0; i < buckets.length; i++) {//穷举出水桶

            if (buckets[i] == 0) {//出水桶已经没水，跳过
                continue;
            }

            for (int j = 0; j < buckets.length; j++) {//穷举进水桶
                int[] temp = buckets.clone();
                if(i == j){//不能既是出水桶又是进水桶
                    continue;
                }

                if(buckets[j] == bucketsLimits[j]){//进水桶已经被注满
                    continue;
                }

                int left = bucketsLimits[j] - buckets[j];//计算注满进水桶需要的水
                if(buckets[i] < left){//出水桶里面的水不够,否则的话就是只需要注入进水桶被注满需要的水
                    left = buckets[i];//全部倒出来
                }

                temp[j] = buckets[j] + left;
                temp[i] = buckets[i] - left;

                Set<String> stepTemps = new LinkedHashSet<>();
                stepTemps.addAll(nodePath);

                stepTemps.add(node);

                change(temp,stepTemps);
            }
        }
    }
}
